package com.rm.zeyou.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rm.zeyou.constant.NumberConstants;
import com.rm.zeyou.constant.OrderConstants;
import com.rm.zeyou.entity.*;
import com.rm.zeyou.exception.ErrorCodeException;
import com.rm.zeyou.exception.ErrorCodeExceptionEnum;
import com.rm.zeyou.mapper.*;
import com.rm.zeyou.response.ApiRestResponse;
import com.rm.zeyou.service.RefundOrderService;
import com.rm.zeyou.util.check.CheckEmptyUtil;
import com.rm.zeyou.util.random.RandomUtils;
import com.rm.zeyou.util.sms.SmsService;
import com.rm.zeyou.vo.request.ApplyRefundVo;
import com.rm.zeyou.vo.response.ApplyRefundIndexResponseVo;
import com.rm.zeyou.vo.response.RefundOrderDetailResponseVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 售后订单表 服务实现类
 * </p>
 *
 * @author YanYang
 * @since 2025-04-01 10:26:48
 */
@Service
public class RefundOrderServiceImpl extends ServiceImpl<RefundOrderMapper, RefundOrder> implements RefundOrderService {
    @Resource
    private RefundOrderMapper refundOrderMapper;
    @Resource
    private UserItemOrderMapper userItemOrderMapper;
    @Resource
    private SmsService smsService;
    @Resource
    private SmsTemplateConfigMapper smsTemplateConfigMapper;
    @Resource
    private TechnicianItemOrderMapper technicianItemOrderMapper;
    @Resource
    private UserCouponMapper userCouponMapper;
    @Resource
    private OrderDictConfigMapper orderDictConfigMapper;
    @Resource
    private TechnicianMapper technicianMapper;

    @Override
    public ApiRestResponse<ApplyRefundIndexResponseVo> applyRefundIndex(User user, String orderNo) {
        ApplyRefundIndexResponseVo responseVo = new ApplyRefundIndexResponseVo();
        UserItemOrder userItemOrder = userItemOrderMapper.selectOneByOrderNo(orderNo);
        //UserItemOrder userItemOrder = userItemOrderMapper.selectOne(new LambdaQueryWrapper<UserItemOrder>()
        //        .eq(UserItemOrder::getOrderNo, orderNo));
        if (CheckEmptyUtil.isEmpty(userItemOrder)) {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.ORDER_EMPTY);
        }
        responseVo.setItemName(userItemOrder.getItemName());
        responseVo.setItemPicture(userItemOrder.getItemPicture());
        responseVo.setItemTime(userItemOrder.getItemTime());
        responseVo.setOrderNum(userItemOrder.getOrderNum());
        responseVo.setOrderTotalPrice(userItemOrder.getOrderTotalPrice());
        responseVo.setApplyRefundPrice(userItemOrder.getOrderTotalPrice());
        Map<String, BigDecimal> map = sumRefundPrice(userItemOrder);

        responseVo.setCanRefundPrice(map.get("refundPrice"));

        return ApiRestResponse.success(responseVo);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public ApiRestResponse<Integer> applyRefund(User user, ApplyRefundVo refundVo) throws Exception {
        UserItemOrder userItemOrder = userItemOrderMapper.selectOneByOrderNo(refundVo.getOrderNo());
        //UserItemOrder userItemOrder = userItemOrderMapper.selectOne(new LambdaQueryWrapper<UserItemOrder>()
        //        .eq(UserItemOrder::getOrderNo, refundVo.getOrderNo()));
        if (CheckEmptyUtil.isEmpty(userItemOrder)) {
            throw new ErrorCodeException(ErrorCodeExceptionEnum.ORDER_EMPTY);
        }
        TechnicianItemOrder technicianItemOrder = technicianItemOrderMapper.selectOne(new LambdaQueryWrapper<TechnicianItemOrder>()
                .eq(TechnicianItemOrder::getOrderNo, refundVo.getOrderNo()));

        //添加售后表
        RefundOrder refundOrder = new RefundOrder();
        refundOrder.setUserId(userItemOrder.getUserId());
        refundOrder.setTid(userItemOrder.getTid());
        String orderNo = RandomUtils.getOrderNo();
        refundOrder.setRefundOrderNo(orderNo);
        refundOrder.setOrderNo(refundVo.getOrderNo());
        refundOrder.setApplyRefundReason(refundVo.getRefundReason());
        refundOrder.setApplyRefundPrice(userItemOrder.getOrderTotalPrice());
        refundOrder.setApplyRefundItemPrice(userItemOrder.getOrderItemPrice());
        refundOrder.setApplyRefundFarePrice(userItemOrder.getOrderFarePrice());
        refundOrder.setPayType(userItemOrder.getPayType());

        Map<String, BigDecimal> map = sumRefundPrice(userItemOrder);
        refundOrder.setCanRefundPrice(map.get("refundPrice"));
        refundOrder.setCanRefundItemPrice(map.get("refundItemPrice"));
        refundOrder.setCanRefundFarePrice(map.get("refundFarePrice"));
        refundOrder.setTechnicianGet(map.get("technicianGet"));


        refundOrder.setAddDescription(refundVo.getRefundDescribe());
        refundOrder.setUserOrderStatus(userItemOrder.getOrderStatus());
        refundOrder.setTechnicianOrderStatus(technicianItemOrder.getOrderStatus());
        refundOrder.setItemName(userItemOrder.getItemName());
        refundOrder.setItemPicture(userItemOrder.getItemPicture());
        refundOrder.setItemTime(userItemOrder.getItemTime());
        refundOrder.setOrderNum(userItemOrder.getOrderNum());
        refundOrder.setOrderTotalPrice(userItemOrder.getOrderTotalPrice());
        refundOrder.setOrderItemPrice(userItemOrder.getOrderItemPrice());
        refundOrder.setOrderFarePrice(userItemOrder.getOrderFarePrice());
        refundOrderMapper.insert(refundOrder);

        //修改订单状态

        userItemOrder.setOrderStatus(OrderConstants.ORDER_STATUS_AFTER_SALE);
        userItemOrderMapper.updateById(userItemOrder);

        technicianItemOrder.setOrderStatus(OrderConstants.ORDER_STATUS_AFTER_SALE);
        int update = technicianItemOrderMapper.updateById(technicianItemOrder);

        //给技师发短信
        Technician technician = technicianMapper.selectById(userItemOrder.getTid());
        String templateCode = smsTemplateConfigMapper.selectOneData("technician_refund_order_notify");
        smsService.orderSendSms(technician.getTechnicianTel(), technician.getTechnicianName(), templateCode);

        //给用户发短信
        String userTemplateCode = smsTemplateConfigMapper.selectOneData("user_refund_order_notify");
        smsService.orderSendSms(userItemOrder.getAddressTel(), user.getUserNikeName(), userTemplateCode);


        return ApiRestResponse.success(update);
    }

    @Override
    public ApiRestResponse<RefundOrderDetailResponseVo> refundOrderDetail(User user, String orderNo) {
        RefundOrder refundOrder = refundOrderMapper.selectOne(new LambdaQueryWrapper<RefundOrder>()
                .eq(RefundOrder::getOrderNo, orderNo));
        UserItemOrder userItemOrder = userItemOrderMapper.selectOneByOrderNo(orderNo);
        //UserItemOrder userItemOrder = userItemOrderMapper.selectOne(new LambdaQueryWrapper<UserItemOrder>()
        //        .eq(UserItemOrder::getOrderNo, orderNo));

        RefundOrderDetailResponseVo responseVo = new RefundOrderDetailResponseVo();
        responseVo.setOrderNo(orderNo);
        responseVo.setAuditStatus(refundOrder.getAuditStatus());
        responseVo.setItemName(refundOrder.getItemName());
        responseVo.setItemPicture(refundOrder.getItemPicture());
        responseVo.setItemTime(refundOrder.getItemTime());
        responseVo.setOrderNum(refundOrder.getOrderNum());
        responseVo.setOrderTotalPrice(refundOrder.getOrderTotalPrice());
        responseVo.setApplyRefundPrice(refundOrder.getApplyRefundPrice());
        responseVo.setCanRefundPrice(refundOrder.getCanRefundPrice());
        responseVo.setAddDescription(refundOrder.getAddDescription());
        responseVo.setApplyRefundReason(refundOrder.getApplyRefundReason());
        responseVo.setCreateTime(refundOrder.getCreateTime());


        Map<String, BigDecimal> map = sumRefundPrice(userItemOrder);

        responseVo.setDiscountPrice(map.get("refundCouponPrice"));
        responseVo.setTechnicianFarePrice(map.get("refundFarePrice"));
        responseVo.setItemRefundPrice(map.get("refundItemPrice"));

        return ApiRestResponse.success(responseVo);
    }

    /**
     * 计算可退款金额
     *
     * @param userItemOrder
     * @return
     * @Date 2025 4月 01 12:14
     */
    @Override
    public Map<String, BigDecimal> sumRefundPrice(UserItemOrder userItemOrder) {
        Map<String, BigDecimal> map = new HashMap<>(3);
        //可退款总金额
        BigDecimal refundPrice = userItemOrder.getOrderTotalPrice();
        //项目可退款金额
        BigDecimal refundItemPrice = userItemOrder.getOrderItemPrice();
        //路费可退款金额
        BigDecimal refundFarePrice = userItemOrder.getOrderFarePrice();
        //优惠券优惠金额
        BigDecimal refundCouponPrice = BigDecimal.ZERO;
        //技师获得
        BigDecimal technicianGet = BigDecimal.ZERO;
        //是否开通会员
        boolean isOpenVip = NumberConstants.ONE_CONSTANTS.equals(userItemOrder.getIsOpenMembership());
        //是否使用优惠券
        if (NumberConstants.ONE_CONSTANTS.equals(userItemOrder.getIsUserCoupon())) {
            UserCoupon userCoupon = userCouponMapper.selectById(userItemOrder.getUserCouponId());
            refundCouponPrice = userCoupon.getCouponSubtract();
            refundPrice = refundPrice.subtract(refundCouponPrice);
        }
        if (OrderConstants.ORDER_STATUS_PENDING_DEPARTURE.equals(userItemOrder.getOrderStatus())) {
            //待出发 全额退
            if (isOpenVip) {
                refundPrice = refundPrice.subtract(userItemOrder.getOpenMemberPrice());
            }
        } else if (OrderConstants.ORDER_STATUS_PENDING_ARRIVAL.equals(userItemOrder.getOrderStatus())) {
            //待到达 有路费并且路费大于50 扣全部路费 如果路费不足50元按50元计算  没有路费扣50
            //最低扣除路费
            BigDecimal minDeductFare = new BigDecimal(orderDictConfigMapper.getArrivalFarePrice());
            //已支付路费
            BigDecimal payFare = userItemOrder.getOrderFarePrice();

            if (payFare.compareTo(minDeductFare) > 0) {
                //已支付路费 > 最低扣除  扣所有路费
                refundPrice = refundPrice.subtract(payFare);
                technicianGet = payFare;
            } else {
                //已支付路费 < 最低扣除  扣除最低（已支付路费+剩余的项目费承担）
                //扣除路费之外的钱
                BigDecimal differencePrice = minDeductFare.subtract(payFare);
                if (refundItemPrice.compareTo(differencePrice) > 0) {
                    //如果项目费用>剩余需要扣除的费用
                    refundPrice = refundPrice.subtract(payFare).subtract(differencePrice);
                    refundItemPrice = refundItemPrice.subtract(differencePrice);
                    technicianGet = minDeductFare;
                } else {
                    //扣除全部项目费
                    refundPrice = BigDecimal.ZERO;
                    refundItemPrice = BigDecimal.ZERO;
                    technicianGet = payFare;
                }

            }

            if (isOpenVip && refundPrice.compareTo(BigDecimal.ZERO) > 0) {
                refundPrice = refundPrice.subtract(userItemOrder.getOpenMemberPrice());
            }
            refundFarePrice = BigDecimal.ZERO;

        } else if (OrderConstants.ORDER_STATUS_PENDING_START.equals(userItemOrder.getOrderStatus())) {
            //已到达 （有路费并且路费大于80 扣全部路费 如果路费不足80元按80元计算  没有路费扣80）+服务金额30%违约金
            //最低扣除路费
            BigDecimal minDeductFare = new BigDecimal(orderDictConfigMapper.getStartFarePrice());
            //已支付路费
            BigDecimal payFare = userItemOrder.getOrderFarePrice();

            if (payFare.compareTo(minDeductFare) > 0) {
                //已支付路费 > 最低扣除 扣所有路费
                refundPrice = refundPrice.subtract(payFare);
                technicianGet = payFare;
            } else {
                //已支付路费 < 最低扣除  扣除最低（已支付路费+剩余的项目费承担）
                //扣除路费之外的钱
                BigDecimal differencePrice = minDeductFare.subtract(payFare);
                if (refundItemPrice.compareTo(differencePrice) > 0) {
                    refundPrice = refundPrice.subtract(payFare).subtract(differencePrice);
                    refundItemPrice = refundItemPrice.subtract(differencePrice);
                    technicianGet = minDeductFare;
                } else {
                    refundPrice = BigDecimal.ZERO;
                    refundItemPrice = BigDecimal.ZERO;
                    technicianGet = payFare;
                }

            }
            //项目扣除比例
            BigDecimal penaltyRate = new BigDecimal(orderDictConfigMapper.getStartItemPriceRate())
                    .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
            BigDecimal penalty = userItemOrder.getOrderItemPrice().multiply(penaltyRate);
            if (refundItemPrice.compareTo(penalty) > 0) {
                //如果项目费用> 需要扣除的金额
                refundPrice = refundPrice.subtract(penalty);
                refundItemPrice = refundItemPrice.subtract(penalty);
            } else {
                //如果项目费用> 需要扣除的金额
                refundPrice = BigDecimal.ZERO;
                refundItemPrice = BigDecimal.ZERO;
            }
            if (isOpenVip && refundPrice.compareTo(BigDecimal.ZERO) > 0) {
                refundPrice = refundPrice.subtract(userItemOrder.getOpenMemberPrice());
            }
            refundFarePrice = BigDecimal.ZERO;
        }
        map.put("refundPrice", refundPrice);
        map.put("refundItemPrice", refundItemPrice);
        map.put("refundFarePrice", refundFarePrice);
        map.put("refundCouponPrice", refundCouponPrice);
        map.put("technicianGet", technicianGet);
        return map;
    }
}
